﻿using System;
using System.Reflection;
using System.Text.RegularExpressions;
using YJKInspectModelFunc.ModelLayer;
using YJKInspectModelFunc.Properties;

namespace YJKInspectModelFunc.ControlLayer
{
	public static class BaseInterfaceFactory<X> where X : class, IResultPackerTag
	{
		public static Assembly UseAssembly
		{
			get
			{
				return BaseInterfaceFactory<X>.useAssembly;
			}
			set
			{
				BaseInterfaceFactory<X>.useAssembly = value;
			}
		}

		public static string NameSpace
		{
			get
			{
				return BaseInterfaceFactory<X>.nameSpace;
			}
			set
			{
				BaseInterfaceFactory<X>.nameSpace = value;
			}
		}

		public static T GetPackerFinder<T>(string cmdName, string defineName = null) where T : class, IPackerFind<X>
		{
			if (!BaseInterfaceFactory<X>.check())
			{
				throw new ModelCheckUtilityException(Resources.Exception_ErrorNonePrepareFactory);
			}
			return BaseInterfaceFactory<X>.GetPackerFinder<T>(BaseInterfaceFactory<X>.useAssembly, BaseInterfaceFactory<X>.nameSpace, cmdName, defineName);
		}

		public static T GetPackerFinder<T>(Assembly useAssembly, string nameSpace, string cmdName, string defineName = null) where T : class, IPackerFind<X>
		{
			return BaseInterfaceFactory<X>.makeProduct<T>(useAssembly, nameSpace, cmdName, defineName);
		}

		public static T GetPackerChecker<T>(string cmdName, string defineName = null) where T : class, IPackerCheck<X>
		{
			if (!BaseInterfaceFactory<X>.check())
			{
				throw new ModelCheckUtilityException(Resources.Exception_ErrorNonePrepareFactory);
			}
			return BaseInterfaceFactory<X>.GetPackerChecker<T>(BaseInterfaceFactory<X>.useAssembly, BaseInterfaceFactory<X>.nameSpace, cmdName, defineName);
		}

		public static T GetPackerChecker<T>(Assembly useAssembly, string nameSpace, string cmdName, string defineName = null) where T : class, IPackerCheck<X>
		{
			return BaseInterfaceFactory<X>.makeProduct<T>(useAssembly, nameSpace, cmdName, defineName);
		}

		public static T GetPackerShower<T>(string cmdName, string defineName = null) where T : class, IPackerResutlShow<X>
		{
			if (!BaseInterfaceFactory<X>.check())
			{
				throw new ModelCheckUtilityException(Resources.Exception_ErrorNonePrepareFactory);
			}
			return BaseInterfaceFactory<X>.GetPackerShower<T>(BaseInterfaceFactory<X>.useAssembly, BaseInterfaceFactory<X>.nameSpace, cmdName, defineName);
		}

		public static T GetPackerShower<T>(Assembly useAssembly, string nameSpace, string cmdName, string defineName = null) where T : class, IPackerResutlShow<X>
		{
			return BaseInterfaceFactory<X>.makeProduct<T>(useAssembly, nameSpace, cmdName, defineName);
		}

		private static T makeProduct<T>(Assembly useAssembly, string nameSpace, string cmdName, string defineName = null) where T : class, IBase<X>
		{
			T result;
			try
			{
				string text = typeof(T).Name;
				text = BaseInterfaceFactory<X>.getUseInterfaceName(text);
				Type typeFromHandle = typeof(X);
				Type typeFromHandle2 = typeof(T);
				string pattern;
				if (!string.IsNullOrWhiteSpace(defineName) && !string.IsNullOrEmpty(defineName))
				{
					pattern = defineName;
				}
				else
				{
					pattern = text + Resources.Str_BaseSpliteForClass + cmdName;
				}
				Type[] types = useAssembly.GetTypes();
				Type type = null;
				foreach (Type type2 in types)
				{
					if ((typeFromHandle2.IsAssignableFrom(type2) || null != type2.GetInterface(typeFromHandle2.Name)) && Regex.IsMatch(type2.Name, pattern))
					{
						type = type2;
						break;
					}
				}
				Type type3;
				if (type.ContainsGenericParameters)
				{
					type3 = type;
					type3 = type3.MakeGenericType(new Type[]
					{
						typeFromHandle
					});
				}
				else
				{
					type3 = type;
				}
				object obj = Activator.CreateInstance(type3);
				if (!(obj is T))
				{
					throw new ModelCheckUtilityException(Resources.Exception_ErrorMakeInterface);
				}
				result = (obj as T);
			}
			catch
			{
				throw new ModelCheckUtilityException(Resources.Exception_ErrorMakeInterface);
			}
			return result;
		}

		private static bool check()
		{
			return !(null == BaseInterfaceFactory<X>.useAssembly) && !string.IsNullOrEmpty(BaseInterfaceFactory<X>.nameSpace) && !string.IsNullOrWhiteSpace(BaseInterfaceFactory<X>.nameSpace);
		}

		private static string getUseInterfaceName(string input)
		{
			return Regex.Replace(Regex.Replace(input, "^I", string.Empty), "`\\d*$", string.Empty);
		}

		private static Assembly useAssembly;

		private static string nameSpace;
	}
}
